package com.be.beadmin.service.impl;

import com.be.beadmin.common.properties.MinioProperties;
import com.be.beadmin.service.entity.FileData;
import com.be.beadmin.service.repository.FileDataRepository;
import io.minio.MinioClient;
import io.minio.PutObjectOptions;
import io.minio.errors.*;
import io.minio.http.Method;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

@Service
public class MinioService {

    @Autowired
    private MinioClient minioClient;


    @Autowired
    private MinioProperties minioProperties;

    @Autowired
    private FileDataRepository fileDataRepository;

    /**
     * 检查桶是否存在
     * @param bucketName
     * @return
     * @throws Exception
     */
    public boolean bucketExists(String bucketName) throws Exception {
        boolean flag = minioClient.bucketExists(bucketName);
        if (flag) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 创建一个桶
     * @param bucketName
     * @return
     * @throws Exception
     */
    public boolean makeBucket(String bucketName) throws Exception {
        boolean flag = bucketExists(bucketName);
        if (!flag) {
            minioClient.makeBucket(bucketName);
            return true;
        } else {
            return false;
        }
    }


    /**
     * 上传一个文件
     * @param bucketName
     * @param multipartFile
     * @throws IOException
     * @throws InvalidBucketNameException
     * @throws InsufficientDataException
     * @throws ErrorResponseException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws InvalidResponseException
     * @throws XmlParserException
     * @throws InternalException
     */
    public void upload(String bucketName,  MultipartFile multipartFile) throws IOException, InvalidBucketNameException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {


        PutObjectOptions options = new PutObjectOptions(multipartFile.getSize(), -1);
        minioClient.putObject(bucketName,multipartFile.getOriginalFilename(), multipartFile.getInputStream(), options);
    }
    //自定义文件名
    public void uploadFile(String bucketName,String fileName,MultipartFile multipartFile) throws IOException, InvalidBucketNameException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        //String fileName = file.getName();
        PutObjectOptions options = new PutObjectOptions(multipartFile.getSize(), -1);

        minioClient.putObject(bucketName,fileName, multipartFile.getInputStream(), options);


    }

    /**
     * 获取一个对象的url
     * @param bucketName
     * @param objectName
     * @return
     * @throws Exception
     */
    public String getObjectUrl(String bucketName, String objectName) throws Exception {

        boolean flag = bucketExists(bucketName);

        String url = "";
        if (flag) {
            url = minioClient.getPresignedObjectUrl(Method.GET,bucketName, objectName, 604800, null);
        }
        return  url;
    }

    /**
     * 文件上传
     * @param multipartFile
     * @return
     */
    @SneakyThrows
    public FileData uploadOne(MultipartFile multipartFile) {
//        String fileTypeCode = FileTypeUtils.getFileTypeCode(multipartFile.getOriginalFilename().toLowerCase());
//        String fileTypeName = FileTypeUtils.getFileTypeName(fileTypeCode);

        String bucketName = minioProperties.getBucketName();
        boolean flag = bucketExists(bucketName);
        if (!flag) {
            makeBucket(bucketName);
        }
        //上传文件
        upload(bucketName, multipartFile);
        //获取文件url
        String url = getObjectUrl(bucketName,multipartFile.getOriginalFilename());
        String[]  strs=url.split("\\?");
        FileData fileData = new FileData();
        fileData.setFilePath(strs[0]);
        fileData.setBucketName(bucketName);
        fileData.setFileName(multipartFile.getOriginalFilename());
        fileData.setFileLength(multipartFile.getSize());
        fileDataRepository.save(fileData);
        return fileDataRepository.save(fileData);
    }



    public FileData uploadOne(MultipartFile multipartFile, String bucketName) throws Exception {
//        String fileTypeCode = FileTypeUtils.getFileTypeCode(multipartFile.getOriginalFilename().toLowerCase());
//        String fileTypeName = FileTypeUtils.getFileTypeName(fileTypeCode);


        boolean flag = bucketExists(bucketName);
        if (!flag) {
            makeBucket(bucketName);
        }
        //上传文件
        upload(bucketName, multipartFile);
        //获取文件url
        String url = getObjectUrl(bucketName,multipartFile.getOriginalFilename());
        String[]  strs=url.split("\\?");
        FileData fileData = new FileData();
        fileData.setFilePath(strs[0]);
        fileData.setBucketName(bucketName);
        fileData.setFileName(multipartFile.getOriginalFilename());
        fileData.setFileLength(multipartFile.getSize());
        fileDataRepository.save(fileData);
        return fileDataRepository.save(fileData);
    }
    /**
     * 文件下载
     * @param bucketName
     * @param objectName
     * @return
     */
    @SneakyThrows
    public InputStream downloadOne(String bucketName, String objectName) {
        boolean flag = bucketExists(bucketName);
        if (flag) {

            return minioClient.getObject(bucketName, objectName);
        }
        return null;
    }

    /**
     * 文件根据FileData下载
     * @param fileData
     * @return
     */
    @SneakyThrows
    public InputStream downLoadByFileData(FileData fileData) {

        boolean flag = bucketExists(fileData.getBucketName());
        if (flag) {

            return minioClient.getObject(fileData.getBucketName(), fileData.getFileName());
        }
        return null;
    }


    /**
     * 根据fileData获取文件路径
     * @param fileData
     * @return
     */
    @SneakyThrows
    public InputStream filePreView(FileData fileData) {
        String bucketName = fileData.getBucketName();
        String objectName = fileData.getFileName();

        InputStream response = minioClient.getObject(bucketName, objectName);

//        String outPath = "./" + objectName.split("\\.")[0] + ".pdf";
        return response;
        //fileService.word2pdf(fileData.getUrl(),outPath);
        /*if (flag) {
            //获取到文件流
            *//*
            String fileTypeCode = fileData.getFileTypeCode();*//*

            String outPath = "./" + fileData.getObjectName().substring(0)
            File inFile = new File(fileData.getUrl());
            File outFile = new File(outPath);
            fileService.word2pdf(fileData.getUrl(),outPath);

        }*/
    }

    /**
     * 文件删除
     * @param bucketName
     * @param objectName
     * @return
     */
    @SneakyThrows
    public boolean removeObject(String bucketName, String objectName) {
        boolean flag = bucketExists(bucketName);
        if (flag) {

            minioClient.removeObject(bucketName, objectName);
            return true;
        }
        return false;
    }
}
